package com.idanchuang.component.base.exception.core;

import com.idanchuang.component.base.exception.exception.AbstractException;
import com.idanchuang.component.base.exception.exception.BusinessException;
import com.idanchuang.component.base.exception.common.ErrorCode;
import com.idanchuang.component.base.exception.exception.SystemException;
import org.slf4j.helpers.MessageFormatter;

import java.util.Objects;

/**
 * 错误码定义仓库
 *
 * @author wuqiang
 */
public class ExFactory {

    private static ExConfigure configure;

    static void init(ExConfigure exConfigure) {
        ExFactory.configure = exConfigure;
    }

    public static ExDefinition of(IErrorEnum code, Object... messages) {
        if (messages == null || messages.length == 0) {
            return code.toDefinition(configure.getApplicationCode());
        }
        return code.toDefinition(configure.getApplicationCode(), messages);
    }

    /**
     * 抛出业务异常
     * @param messagePattern 异常信息 支持占位符
     * @param messages 填充异常信息的占位符
     * @return ..
     */
    public static AbstractException throwBusiness(Object messagePattern, Object... messages) {
        Objects.requireNonNull(messagePattern, "请描述业务异常");
        if (messagePattern instanceof String) {
            throw throwWithFormatter(ErrorCode.BUSINESS_ERROR, (String) messagePattern, messages);
        }
        throw throwWith(ErrorCode.BUSINESS_ERROR, messagePattern);
    }

    /**
     * 抛出系统异常
     * @param messagePattern 异常信息 支持占位符
     * @param messages 填充异常信息的占位符
     * @return ..
     */
    public static AbstractException throwSystem(Object messagePattern, Object... messages) {
        Objects.requireNonNull(messagePattern, "请描述系统异常");
        if (messagePattern instanceof String) {
            throw throwWithFormatter(ErrorCode.SYSTEM_ERROR, (String) messagePattern, messages);
        }
        throw throwWith(ErrorCode.SYSTEM_ERROR, messagePattern);
    }

    /**
     * 抛出参数异常
     * @param messagePattern 异常信息 支持占位符
     * @param messages 填充异常信息的占位符
     * @return ..
     */
    public static AbstractException throwParamError(Object messagePattern, Object... messages) {
        Objects.requireNonNull(messagePattern, "请描述参数异常");
        if (messagePattern instanceof String) {
            throw throwWithFormatter(ErrorCode.PARAM_ERROR, (String) messagePattern, messages);
        }
        throw throwWith(ErrorCode.PARAM_ERROR, messagePattern);
    }

    public static AbstractException throwCommon(ErrorCode code, Object... messages) {
        throw throwWith(code, messages);
    }

    /**
     * 抛出指定异常, 并支持占位方式构造message
     *
     * 注意: 使用此方法时, code枚举中的msg必须包含一个{}占位符
     *
     * @param code 异常枚举
     * @param messagePattern 异常信息模板
     * @param messages 填充异常信息模板的占位符
     * @return ..
     */
    public static AbstractException throwWithFormatter(IErrorEnum code, String messagePattern, Object... messages) {
        if (messagePattern == null) {
            throw throwWith(code);
        }
        if (messages != null && messages.length > 0) {
            messagePattern = MessageFormatter.arrayFormat(messagePattern, messages).getMessage();
        }
        throw throwWith(code, messagePattern);
    }

    public static AbstractException throwWith(IErrorEnum code, Object... messages) {
        throw throwWith(of(code, messages));
    }

    public static AbstractException throwWith(ExDefinition exDefinition) {
        if (exDefinition.getExType().equals(ExType.BUSINESS_ERROR)) {
            throw new BusinessException(exDefinition);
        } else {
            throw new SystemException(exDefinition);
        }
    }

    public static ExDefinition withCopyRight(ExDefinition code) {
        return code.tipsErrorCode(configure.getCopyrights());
    }

}
